package com.ruoyi.seckill.service.impl;

import com.ruoyi.seckill.domain.SeckillRecord;
import com.ruoyi.seckill.feign.OrderFeignService;
import com.ruoyi.seckill.mapper.SeckillRecordMapper;
import com.ruoyi.seckill.service.SeckillTestService;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.concurrent.TimeUnit;

@Service
public class SeckillTestServiceImpl implements SeckillTestService {

    @Autowired
    private SeckillRecordMapper seckillRecordMapper;

    @Autowired
    private OrderFeignService orderFeignService;

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @Autowired
    private RedissonClient redissonClient;

    private static final String LOCK_KEY_PREFIX = "seckill:lock:";

    @Override
    @Transactional
    public String createSeckill(String userId) {
        // 每个用户锁自己的行为，防止重复点击或并发请求（幂等防护）
        String lockKey = "seckill:lock:1001:" + userId;
        RLock lock = redissonClient.getLock(lockKey);

        boolean isLocked = false;
        try {
            // 最多等3秒，拿到锁后自动续命10秒（防止业务长时间阻塞）
            isLocked = lock.tryLock(3, 10, TimeUnit.SECONDS);
            if (!isLocked) {
                System.out.println("用户[{}] 获取锁失败" + userId);
                return "系统繁忙，请稍后再试";
            }

            // 幂等性检查：该用户是否已抢过
            String userFlagKey = "seckill:user:1001:" + userId;
            if (Boolean.TRUE.equals(redisTemplate.hasKey(userFlagKey))) {
                System.out.println("你已经抢过啦" + userId);
                return "你已经抢过啦";
            }

            // 原子扣减库存
            Long stock = redisTemplate.opsForValue().decrement("seckill:stock:1001");
            if (stock == null || stock < 0) {
                System.out.println("已售罄" + userId);
                return "已售罄";
            }

            try {
                // 插入本地秒杀记录
                SeckillRecord record = new SeckillRecord();
                record.setUserId(Long.valueOf(userId));
                record.setGoodsId(1001L);
                record.setStatus(0);
                seckillRecordMapper.insert(record);

                // 远程创建订单
                String result = orderFeignService.createOrder(userId);

                // ✅ 所有操作成功后，设置抢购标记
                redisTemplate.opsForValue().set(userFlagKey, "1");

                return result;

            } catch (Exception e) {
                // ❗重要：任何异常都要回滚库存
                redisTemplate.opsForValue().increment("seckill:stock:1001");
                throw new RuntimeException("下单失败，库存已回滚", e);
            }

        } catch (Exception e) {
            System.out.println("出错了" + userId);
            throw new RuntimeException("秒杀失败", e);
        } finally {
            if (isLocked) {
                lock.unlock();
            }
        }
    }

}
